/*
 * @file     g_hspi.h
 * @brief    source file for setting high speed spi
 *
 * Change Logs:
 * Date            Author             Version        Notes
 * 2020-11-12      zhupengkun         V1.0.0         the first version
 */

#ifndef __G_HSPI_H__
#define __G_HSPI_H__

#ifdef __cplusplus
extern "C"
{
#endif

/* Includes ------------------------------------------------------------------*/
#include "g_1903.h"
#include "g_system.h"


//================ group definitions ====================
/** @defgroup HSPI_Mode
  * @{
  */
#define HSPI_Mode_Host                                          (0) /*!< Spi host mode. */
#define HSPI_Mode_Slave                                         (1) /*!< Spi slave mode. */
#define Is_HSPI_Mode(MODE)                                      (((MODE) == HSPI_Mode_Host) ||\
                                                                ((MODE)  == HSPI_Mode_Slave))

/** @defgroup HSPI_TxRx_Sequence
  * @{
  */
#define HSPI_TxRx_Sequence_Concurrent                           (0<<6) /*!< Tx and rx concurrently. */
#define HSPI_TxRx_Sequence_Tx_First                             (1<<6) /*!< Rx after tx. */
#define Is_HSPI_TxRx_Sequence(SEQUENCE)                         (((SEQUENCE) == HSPI_TxRx_Sequence_Concurrent) ||\
                                                                ((SEQUENCE)  == HSPI_TxRx_Sequence_Tx_First))

/** @defgroup HSPI_Clock_Phase
  * @{
  */
#define HSPI_CPHA_First_Edge                                    (0<<5) /*!< The clock active edge for the bit capture is first edge. */
#define HSPI_CPHA_Second_Edge                                   (1<<5) /*!< The clock active edge for the bit capture is second edge. */
#define Is_HSPI_CPHA(EDGE)                                      (((EDGE) == HSPI_CPHA_First_Edge) ||\
                                                                ((EDGE)  == HSPI_CPHA_Second_Edge))

/** @defgroup HSPI_Clock_Polarity
  * @{
  */
#define HSPI_CPOL_Low                                           (0<<4) /*!< The serial clock steady state is low. */
#define HSPI_CPOL_High                                          (1<<4) /*!< The serial clock steady state is high. */
#define Is_HSPI_CPOL(PHASE)                                     (((PHASE) == HSPI_CPOL_Low) ||\
                                                                ((PHASE)  == HSPI_CPOL_High))

/** @defgroup HSPI_Hw_Start_Sel
  * @{
  */
#define HSPI_Hw_Start_Sel_DMA0                                  (0<<2) /*!< The select of lines irq is DCMI DMA0. */
#define HSPI_Hw_Start_Sel_DMA1                                  (1<<2) /*!< The select of lines irq is DCMI DMA1. */
#define Is_HSPI_Hw_Start_Sel(SELECT)                            (((SELECT) == HSPI_Hw_Start_Sel_DMA0) ||\
                                                                ((SELECT)  == HSPI_Hw_Start_Sel_DMA1))

/** @defgroup HSPI_Interrupt
  * @{
  */
#define Start_Over_Quick_IRQ                                    (1<<5)
#define RxFifo_Overflow_IRQ                                     (1<<4)
#define RxFifo_High_IRQ                                         (1<<3)
#define TxFifo_Overflow_IRQ                                     (1<<2)
#define TxFifo_Low_IRQ                                          (1<<1)
#define DMA_Done_IRQ                                            (1<<0)
#define Is_HSPI_IRQ_Config(IRQ)                                 ((((IRQ) & 0xc0) == 0x00) && ((IRQ) != 0x00))
#define Is_HSPI_IRQ_Clear(IRQ)                                  ((((IRQ) & 0xc0) == 0x00) && ((IRQ) != 0x00))

/** @defgroup HSPI_Status
  * @{
  */
//RISR register
#define Start_Over_Quick_RIS                                    ((1<<5) | 0x100000)
#define RxFifo_Overflow_RIS                                     ((1<<4) | 0x100000)
#define RxFifo_High_RIS                                         ((1<<3) | 0x100000)
#define TxFifo_Overflow_RIS                                     ((1<<2) | 0x100000)
#define TxFifo_Low_RIS                                          ((1<<1) | 0x100000)
#define DMA_Done_RIS                                            ((1<<0) | 0x100000)
//MISR register
#define Start_Over_Quick_MIS                                    (1<<5)
#define RxFifo_Overflow_MIS                                     (1<<4)
#define RxFifo_High_MIS                                         (1<<3)
#define TxFifo_Overflow_MIS                                     (1<<2)
#define TxFifo_Low_MIS                                          (1<<1)
#define DMA_Done_MIS                                            (1<<0)

#define Is_HSPI_Get_IRQ_Status(FLAG)                            (((FLAG) == Start_Over_Quick_RIS) ||\
                                                                ((FLAG)  == RxFifo_Overflow_RIS ) ||\
                                                                ((FLAG)  == RxFifo_High_RIS     ) ||\
                                                                ((FLAG)  == TxFifo_Overflow_RIS ) ||\
                                                                ((FLAG)  == TxFifo_Low_RIS      ) ||\
                                                                ((FLAG)  == DMA_Done_RIS        ) ||\
                                                                ((FLAG)  == Start_Over_Quick_MIS) ||\
                                                                ((FLAG)  == RxFifo_Overflow_MIS ) ||\
                                                                ((FLAG)  == RxFifo_High_MIS     ) ||\
                                                                ((FLAG)  == TxFifo_Overflow_MIS ) ||\
                                                                ((FLAG)  == TxFifo_Low_MIS      ) ||\
                                                                ((FLAG)  == DMA_Done_MIS        ))

/** @defgroup HSPIM_Private_Defines
  * @{
  */
 //ctrl register
#define HSPI_CTRL_SLAVE_MODE_BIT                                (24)
#define HSPI_CTRL_RX_ADJ_CLK_BIT                                (20)
#define HSPI_CTRL_CLK_DIV_BIT                                   (16)
#define HSPI_CTRL_TRX_DLY_BIT                                   (12)
#define HSPI_CTRL_FIFO_SW_EN_BIT                                (8)
#define HSPI_CTRL_NCS_DLY_BIT                                   (8)
#define HSPI_CTRL_RX_ADJ_EN_BIT                                 (7)

#define HSPI_FIFO_SW_ENABLE_BIT                                 (11)
#define HSPI_RX_ADJ_ENABLE_BIT                                  (7)
#define HSPI_START_BIT                                          (3)
#define HSPI_HW_START_ENABLE_BIT                                (1)
#define HSPI_ENABLE_BIT                                         (0)
//fifo register
#define HSPI_FIFO_AUTO_RST_BIT                                  (11)
#define HSPI_RX_FIFO_READ_BIT                                   (8)
#define HSPI_FIFO_SW_RST_BIT                                    (3)
#define HSPI_TX_FIFO_READ_BIT                                   (0)
//dma register
#define HSPI_PINGPANG_ENABLE_BIT                                (6)
#define HSPI_RX_FIXED_ADDR_BIT                                  (5)
#define HSPI_TX_FIXED_ADDR_BIT                                  (4)
#define HSPI_DMA_MANUL_START_BIT                                (3)
#define HSPI_DMA_AUTO_START_BIT                                 (1)
#define HSPI_DMA_ENABLE_BIT                                     (0)

//irq
#define HSPI_IRQ_RX_FIFO_WATER_LEVEL_BIT                        (28)
#define HSPI_IRQ_TX_FIFO_WATER_LEVEL_BIT                        (24)
#define HSPI_IRQ_DONE_EN                                        (16)
#define HSPI_IRQ_DONE_MIS                                       (8)

//hspi rxadjclk
#define HSPI_CTRL_RXADJCLK_0                                    ((uint8_t)0x00)
#define HSPI_CTRL_RXADJCLK_1                                    ((uint8_t)0x01)
#define HSPI_CTRL_RXADJCLK_2                                    ((uint8_t)0x02)
#define HSPI_CTRL_RXADJCLK_3                                    ((uint8_t)0x03)
#define HSPI_CTRL_RXADJCLK_4                                    ((uint8_t)0x04)
#define HSPI_CTRL_RXADJCLK_5                                    ((uint8_t)0x05)
#define HSPI_CTRL_RXADJCLK_6                                    ((uint8_t)0x06)
#define HSPI_CTRL_RXADJCLK_7                                    ((uint8_t)0x07)
#define HSPI_CTRL_RXADJCLK_8                                    ((uint8_t)0x08)
#define HSPI_CTRL_RXADJCLK_9                                    ((uint8_t)0x09)
#define HSPI_CTRL_RXADJCLK_10                                   ((uint8_t)0x0a)
#define HSPI_CTRL_RXADJCLK_11                                   ((uint8_t)0x0b)
#define HSPI_CTRL_RXADJCLK_12                                   ((uint8_t)0x0c)
#define HSPI_CTRL_RXADJCLK_13                                   ((uint8_t)0x0d)
#define HSPI_CTRL_RXADJCLK_14                                   ((uint8_t)0x0e)
#define HSPI_CTRL_RXADJCLK_15                                   ((uint8_t)0x0f)
#define IS_HSPI_CTRL_RXADJCLK(rxadjclk)                         ((rxadjclk & 0xf0) == 0)

//hspi ClkDiv
#define HSPI_CTRL_CLKDIV_DIV0                                   ((uint8_t)0x00)
#define HSPI_CTRL_CLKDIV_DIV1                                   ((uint8_t)0x01)
#define HSPI_CTRL_CLKDIV_DIV2                                   ((uint8_t)0x02)
#define HSPI_CTRL_CLKDIV_DIV3                                   ((uint8_t)0x03)
#define HSPI_CTRL_CLKDIV_DIV4                                   ((uint8_t)0x04)
#define HSPI_CTRL_CLKDIV_DIV5                                   ((uint8_t)0x05)
#define HSPI_CTRL_CLKDIV_DIV6                                   ((uint8_t)0x06)
#define HSPI_CTRL_CLKDIV_DIV7                                   ((uint8_t)0x07)
#define HSPI_CTRL_CLKDIV_DIV8                                   ((uint8_t)0x08)
#define HSPI_CTRL_CLKDIV_DIV9                                   ((uint8_t)0x09)
#define HSPI_CTRL_CLKDIV_DIV10                                  ((uint8_t)0x0a)
#define HSPI_CTRL_CLKDIV_DIV11                                  ((uint8_t)0x0b)
#define HSPI_CTRL_CLKDIV_DIV12                                  ((uint8_t)0x0c)
#define HSPI_CTRL_CLKDIV_DIV13                                  ((uint8_t)0x0d)
#define HSPI_CTRL_CLKDIV_DIV14                                  ((uint8_t)0x0e)
#define HSPI_CTRL_CLKDIV_DIV15                                  ((uint8_t)0x0f)
#define IS_HSPI_CTRL_CLKDIV(div)                                ((div & 0xf0) == 0)

//hspi TxRxDly
#define HSPI_CTRL_TXRXDLY_0                                     ((uint8_t)0x00)
#define HSPI_CTRL_TXRXDLY_1                                     ((uint8_t)0x01)
#define HSPI_CTRL_TXRXDLY_2                                     ((uint8_t)0x02)
#define HSPI_CTRL_TXRXDLY_3                                     ((uint8_t)0x03)
#define HSPI_CTRL_TXRXDLY_4                                     ((uint8_t)0x04)
#define HSPI_CTRL_TXRXDLY_5                                     ((uint8_t)0x05)
#define HSPI_CTRL_TXRXDLY_6                                     ((uint8_t)0x06)
#define HSPI_CTRL_TXRXDLY_7                                     ((uint8_t)0x07)
#define HSPI_CTRL_TXRXDLY_8                                     ((uint8_t)0x08)
#define HSPI_CTRL_TXRXDLY_9                                     ((uint8_t)0x09)
#define HSPI_CTRL_TXRXDLY_10                                    ((uint8_t)0x0a)
#define HSPI_CTRL_TXRXDLY_11                                    ((uint8_t)0x0b)
#define HSPI_CTRL_TXRXDLY_12                                    ((uint8_t)0x0c)
#define HSPI_CTRL_TXRXDLY_13                                    ((uint8_t)0x0d)
#define HSPI_CTRL_TXRXDLY_14                                    ((uint8_t)0x0e)
#define HSPI_CTRL_TXRXDLY_15                                    ((uint8_t)0x0f)
#define IS_HSPI_CTRL_TXRXDLY(txrxdly)                           ((txrxdly & 0xf0) == 0)

//hspi NcsDly
#define HSPI_CTRL_NCSDLY_0                                      ((uint8_t)0x00)
#define HSPI_CTRL_NCSDLY_1                                      ((uint8_t)0x01)
#define HSPI_CTRL_NCSDLY_2                                      ((uint8_t)0x02)
#define HSPI_CTRL_NCSDLY_3                                      ((uint8_t)0x03)
#define HSPI_CTRL_NCSDLY_4                                      ((uint8_t)0x04)
#define HSPI_CTRL_NCSDLY_5                                      ((uint8_t)0x05)
#define HSPI_CTRL_NCSDLY_6                                      ((uint8_t)0x06)
#define HSPI_CTRL_NCSDLY_7                                      ((uint8_t)0x07)
#define IS_HSPI_CTRL_NCSDLY(ncsdly)                             ((ncsdly & 0xf8) == 0)

//hspi RxFifoWaterlevel
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_0                        ((uint8_t)0x00)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_1                        ((uint8_t)0x01)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_2                        ((uint8_t)0x02)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_3                        ((uint8_t)0x03)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_4                        ((uint8_t)0x04)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_5                        ((uint8_t)0x05)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_6                        ((uint8_t)0x06)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_7                        ((uint8_t)0x07)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_8                        ((uint8_t)0x08)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_9                        ((uint8_t)0x09)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_10                       ((uint8_t)0x0a)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_11                       ((uint8_t)0x0b)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_12                       ((uint8_t)0x0c)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_13                       ((uint8_t)0x0d)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_14                       ((uint8_t)0x0e)
#define HSPI_FIFOCTRL_RXFIFOWATERLEVEL_15                       ((uint8_t)0x0f)
#define IS_HSPI_FIFOCTRL_RXFIFOWATERLEVEL(rxfifowaterlevrel)    ((rxfifowaterlevrel & 0xf0) == 0)

//hspi Fifo TxFifoWaterlevel
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_0                        ((uint8_t)0x00)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_1                        ((uint8_t)0x01)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_2                        ((uint8_t)0x02)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_3                        ((uint8_t)0x03)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_4                        ((uint8_t)0x04)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_5                        ((uint8_t)0x05)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_6                        ((uint8_t)0x06)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_7                        ((uint8_t)0x07)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_8                        ((uint8_t)0x08)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_9                        ((uint8_t)0x09)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_10                       ((uint8_t)0x0a)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_11                       ((uint8_t)0x0b)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_12                       ((uint8_t)0x0c)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_13                       ((uint8_t)0x0d)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_14                       ((uint8_t)0x0e)
#define HSPI_FIFOCTRL_TXFIFOWATERLEVEL_15                       ((uint8_t)0x0f)
#define IS_HSPI_FIFOCTRL_TXFIFOWATERLEVEL(txfifowaterlevel)     ((txfifowaterlevel & 0xf0) == 0)

//================ struct definitions ====================
/**
  * @brief   HSPI_Init_Structure_Definition
  */
typedef struct
{

    unsigned int SlaveMode;                  /*!< Specifies the high speed spi mode.
                        This parameter can be a value of @ref HSPI_Mode */

  unsigned char RxAdjClk;                     /*!< Specifies the received phase adjustment value,
                                                the sampling time is delayed (RxAdjClk + 1)*spi_clk clock cycles,
                                                shall not be greater than ClkDiv value.
                        This parameter can be a value between 0x00 and 0x0F */

  unsigned char ClkDiv;                       /*!< Specifies the clock frequency division factor, division value is (ClkDiv + 1)*2.
                        This parameter can be a value between 0x00 and 0x0F */

  unsigned char TxRxDly;                      /*!< Specifies the send and receive protection interval, interval value is spi_clk*(TxRxDly + 1)*4.
                        This parameter can be a value between 0x00 and 0x0F */

  unsigned char NcsDly;                        /*!< Specifies the delay time of NCS,delay value is spi_clk*(NcsDly + 1).
                        This parameter can be a value between 0x00 and 0x07 */

    unsigned int RxAdjEn;                       /*!< Specifies the Receive phase adjustment enable switch.
                        This parameter can be a value between 0x00 and 0x01 */

    unsigned int TxRxSeq;                       /*!< Specifies the tx and rx sequence control:
                        This parameter can be a value of @ref HSPI_TxRx_Sequence */

  unsigned int CPHA;                          /*!< Specifies the clock active edge for the bit capture.
                                                This parameter can be a value of @ref HSPI_Clock_Phase */

  unsigned int CPOL;                          /*!< Specifies the serial clock steady state.
                                                This parameter can be a value of @ref HSPI_Clock_Polarity */

  unsigned int SpiHwStartSel;                 /*!< Specifies the DCMI DMA select of lines irq.
                                                This parameter can be a value of @ref HSPI_Hw_Start_Sel */

  unsigned char RxFifoData;                    /*!< Specifies the 8-bit data of rx fifo.
                                                When write register, this byte is written to rx fifo directly,
                                                when read register, it represents the current value of rx fifo.
                                                This parameter can be a value between 0x00 and 0xff */

  unsigned char TxFifoData;                    /*!< Specifies the 8-bit data of tx fifo.
                                                When write register, this byte is written to tx fifo directly,
                                                when read register, it represents the current value of tx fifo.
                                                This parameter can be a value between 0x00 and 0xff */

    unsigned char RxFifoWaterlevel;              /*!< Specifies the rx fifo waterlevel.
                        This parameter can be a value between 0x00 and 0x07 */

    unsigned char TxFifoWaterlevel;              /*!< Specifies the tx fifo waterlevel.
                        This parameter can be a value between 0x00 and 0x07 */

    unsigned int TxStartAddr;                   /*!< Specifies the starting address to send data in RAM.
                        This parameter can be a value between 0x00 and 0xfffff */

    unsigned int RxStartAddr;                   /*!< Specifies the starting address to recieve data in RAM.
                        This parameter can be a value between 0x00 and 0xfffff */

    unsigned int TxLen;                         /*!< Specifies the length to send data, receive only when config 0.
                        This parameter can be a value between 0x00 and 0xfffff */

    unsigned int RxLen;                         /*!< Specifies the length to recieve data, send only when config 0.
                        This parameter can be a value between 0x00 and 0xfffff */
} G_HSPI_InitTypeDef;




void G_HSPI_DeInit(void);

void G_HSPI_Init(G_HSPI_InitTypeDef* HSPI_InitStruct);

void G_HSPI_HwStartCmd(G_FunctionalState newstate);

void G_HSPI_EnableCmd(G_FunctionalState newstate);

void G_HSPI_PingpangEnableCmd(G_FunctionalState newstate);

void G_HSPI_DmaEnableCmd(G_FunctionalState newstate);

void G_HSPI_DmaAutoStartCmd(G_FunctionalState newstate);

void G_HSPI_ITConfig(unsigned int irq, G_FunctionalState newstate);

void G_HSPI_ITClear(unsigned int irq, G_FunctionalState newstate);

G_FlagStatus G_HSPI_GetITStatus(unsigned int irq);

void G_HSPI_SendData(unsigned char data);

void G_HSPI_SendBuff(unsigned char *txbuff, unsigned int txlen);

void G_HSPI_DMASendBuff(unsigned char *txbuff, unsigned int txlen);

void G_HSPI_ReceiveData(unsigned char *rxbuff, unsigned int rxlen);

void G_HSPI_SendAndReceiveData(unsigned char *txbuff, unsigned int txlen, unsigned char *rxbuff, unsigned int rxlen);

uint8_t G_HSPI_DMASendBusy(void);
#ifdef __cplusplus
}
#endif

#endif  /* __G_HSPI_H__ */
